#pragma once

#include <iostream>
#include <string>
#include <string.h>
#include <errno.h>
#include <sys/epoll.h>

#include "log.hpp"
#include "err.hpp"

const static int defaultepfd = -1;
const static int gsize = 128;

class Epoller
{
public:
    Epoller() : _epfd(defaultepfd)
    {
    }
    // 创建epoll模型
    void Create(int size = gsize)
    {
        _epfd = epoll_create(size);
        if (_epfd < 0)
        {
            logMessage(Fatal, "epoll create error,%d:%s", errno, strerror(errno));
            exit(EPCRE_ERR);
        }
    }
    // 添加事件
    bool AddMovEvent(int fd, uint32_t events, int op)
    {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = fd;
        // 添加关心事件
        int n = epoll_ctl(_epfd, op, fd, &ev);
        if (n < 0)
        {
            logMessage(Warning, "epoll add error,%d:%s", errno, strerror(errno));
            return false;
        }
        return true;
    }
    // 移除事件
    bool DelEvent(int fd)
    {
        return epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, nullptr) == 0;
    }
    // 拿取底层就绪的事件
    int Wait(struct epoll_event *revs, int num, int timeout)
    {
        return epoll_wait(_epfd, revs, num, timeout);
    }

    int Fd()
    {
        return _epfd;
    }

    // 关闭epoll模型的文件描述符
    void Close()
    {
        if (_epfd != defaultepfd)
            close(_epfd);
    }

    ~Epoller()
    {
    }

private:
    int _epfd; // epoll模型的文件描述符
};